package com.kujawnode.aspect;

import com.kujawnode.commons.DataScope;
import com.kujawnode.constant.Constants;
import com.kujawnode.model.TUser;
import com.kujawnode.query.BaseQuery;
import com.kujawnode.utils.JWTUtils;
import jakarta.servlet.http.HttpServletRequest;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.util.List;

/**
 * @version 1.0
 * @Author kujaw
 * @Date 2025/7/15 18:55
 * @注释
 */
@Aspect
@Component
public class DataScopeAspect {

    //切入点
    @Pointcut(value = "@annotation(com.kujawnode.commons.DataScope)")
    public void pointCut() {
    }

    @Around(value = "pointCut()")
    public Object process(ProceedingJoinPoint joinPoint) throws Throwable {
        MethodSignature methodSignature = (MethodSignature)joinPoint.getSignature();

        //拿到方法的注解
        DataScope dataScope = methodSignature.getMethod().getDeclaredAnnotation(DataScope.class);

        String tableAlias = dataScope.tableAlias();
        String tableField = dataScope.tableField();

        //在spring web容器中，可以拿到当前请求，spring security中也可以
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();

        String token = request.getHeader(Constants.TOKEN_NAME);
        //从token中解析出用户是管理员还是用户
        TUser tUser = JWTUtils.parseUserFromJWT(token);

        List<String> roleList = tUser.getRoleList();
        if(!roleList.contains("admin")){
            Object params = joinPoint.getArgs()[0]; //拿到第一个参数
            if(params instanceof BaseQuery){
                BaseQuery baseQuery = (BaseQuery) params;
                baseQuery.setFilterSQL("and " + tableAlias + "." + tableField + " = " + tUser.getId());
            }
        }
        return joinPoint.proceed();
    }

}
